package main

import (
	"fmt"
	"log"
	"math/rand"
	"strconv"
	"sync"
	"time"
)

//生产随机数18位数字
func RandInt64() string {
	//以纳秒为随机种子
	rand.Seed(time.Now().UnixNano())
	//生成一个随机uint64
	randNum := rand.Uint64()
	//打印 生成的随机数
	fmt.Println("randNum-->", randNum)
	//休眠1纳秒，避免多次调用时,产生相同的int64值
	time.Sleep(time.Nanosecond * 1)
	//将随机数 转换为10进制字符串
	tmp := strconv.FormatUint(randNum, 10)
	//截取前18位字符串
	if len(tmp) >= 18 {
		return tmp[:18]
	} else {
		//不足18位，使用前面的字符串进行弥补
		cha := 18 - len(tmp)
		return tmp + tmp[:cha]
	}
}
func main() {
	//AddChanTest()
	fmt.Println("fannNum=", RandInt64())
	fmt.Println("fannNum=", RandInt64())
	fmt.Println("fannNum=", RandInt64())
	chanDemo1()
	fmt.Println("--------------------------")
	chanDemo2()
}

//使用的chan 来实现的
func chanDemo2() {
	//1、声明一个chan进行读写数据，
	ch2 := make(chan string)
	//一个chan 进行阻塞,通知里面的数据
	chInt := make(chan int, 2)
	//2、启用一个协程进行写数据
	go func() {
		ch2 <- "端午节是纪念屈原"
		chInt <- 1
		close(ch2)
	}()
	//3、启用另一个协程读数据
	go func() {
		cont := <-ch2
		fmt.Println("接受的数据：", cont)
		chInt <- 2
		close(chInt)
	}()
	//4、处理阻塞中的chan 的数据
	for num := range chInt {
		fmt.Println(num)
	}
	fmt.Println("主程序结束了")
}

//你用wg 的阻塞 实现程序的等待
func chanDemo1() {
	//声明一个chan string 用来进行消息的传递
	ch1 := make(chan string)
	//创建wg 进行协程的阻塞，让协程执行完成
	var wg sync.WaitGroup
	//协程数量默认定义为2
	wg.Add(2)
	//开启一个协程
	go func() {
		//chan 传值
		ch1 <- "今天是的2020年端午佳节"
		//协程数量减一
		wg.Done()
	}()
	//开启协程进行数据的读取
	go func() {
		content := <-ch1
		fmt.Println("读取到的数据：", content)
		wg.Done()
	}()
	wg.Wait()
	//主 协程结束
	fmt.Println("主协程结束退出了")
}

func AddChanTest() {
	//chan 数组
	chs := make([]chan int, 10)
	for i := 0; i < 10; i++ {
		//每执行一次 启一次协程
		chs[i] = make(chan int)
		go AddChan(i, i, chs[i])
	}
	//遍历的 所有的chan ，当没有的时候处于阻塞状态里
	for i, v := range chs {
		log.Println("chan=", <-v, ",index=", i)
	}
}
func AddChan(i, j int, c chan int) {
	//将2个数值相加同时打印
	x := i + j
	log.Println(x)
	//计算完成后 给管道写入i
	c <- i
}

//----------------------------
func Add(in chan int) chan int {
	out := make(chan int)
	go func() {
		for v := range in {
			out <- v + 100
		}
		close(out)
	}()
	return out
}

func TestChan() {
	ch := make(chan int)
	go func() {
		for i := 0; i < 4; i++ {
			ch <- i
		}
		close(ch)
	}()

	d := Add(Add(Add(Add(ch))))
	for v := range d {
		log.Println(v)
	}
}
